package com.xbongbong.workflow.service.strategy.data.impl;

import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormDataEntity;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.enums.FundAccountFlowTypeEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.enums.PaySheetTypeEnum;
import com.xbongbong.paas.enums.SheetTypeEnum;
import com.xbongbong.paas.enums.TaskTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.pojo.dto.SaasFormSaveDTO;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.Arith;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.paas.util.FormDataUtil;
import com.xbongbong.pro.domain.entity.UpdateDataEntity;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.formdata.pojo.SaasNeedRedundantAttrPojo;
import com.xbongbong.pro.paymentsheet.pojo.dto.PaymentSheetSaveDTO;
import com.xbongbong.pro.sheet.pojo.SheetAttrPojo;
import com.xbongbong.pro.team.pojo.TeamSavePaySheetPojo;
import com.xbongbong.pro.workflow.enums.WorkflowOperateEnum;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.domain.entity.FundAccountFlowEntity;
import com.xbongbong.saas.domain.entity.PayPlanSheetUserEntity;
import com.xbongbong.saas.domain.entity.ext.PayPlanSheetEntityExt;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.PaySheetEnum;
import com.xbongbong.saas.enums.business.PaymentSheetEnum;
import com.xbongbong.saas.help.FundHelp;
import com.xbongbong.saas.help.SaasPayPlanHelper;
import com.xbongbong.saas.help.SaasPaySheetHelper;
import com.xbongbong.saas.help.SaasRefundHelper;
import com.xbongbong.saas.help.workflow.PayAndPaymentSheetHelp;
import com.xbongbong.saas.help.workflow.PurchaseHelp;
import com.xbongbong.saas.model.FundAccountFlowModel;
import com.xbongbong.saas.model.PaasFormSubDataModel;
import com.xbongbong.saas.model.PayPlanSheetModel;
import com.xbongbong.saas.model.PayPlanSheetUserModel;
import com.xbongbong.saas.service.PayPlanSheetService;
import com.xbongbong.saas.service.toolbox.help.SaasSaveHelper;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import com.xbongbong.workflow.domain.entity.WorkflowBackupDataEntity;
import com.xbongbong.workflow.model.WorkflowBackupDataModel;
import com.xbongbong.workflow.pojo.Data;
import com.xbongbong.workflow.pojo.WorkflowTransferPOJO;
import com.xbongbong.workflow.service.strategy.data.AbstractWorkflowDataStrategy;
import com.xbongbong.workflow.service.strategy.data.WorkflowDataProcessStrategy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 *
 * @author 魏荣杰
 *
 */
@Service
public class WorkflowPaySheetStrategy extends AbstractWorkflowDataStrategy implements WorkflowDataProcessStrategy {


    private static Logger log = LoggerFactory.getLogger(WorkflowPaySheetStrategy.class);


    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private PayAndPaymentSheetHelp payAndPaymentSheetHelp;
    @Resource
    private PayPlanSheetModel payPlanSheetModel;
    @Resource
    private WorkflowBackupDataModel workflowBackupDataModel;
    @Resource
    private PaasFormSubDataModel paasFormSubDataModel;
    @Resource
    private SaasSaveHelper saasSaveHelper;
    @Resource
    private SaasPayPlanHelper saasPayPlanHelper;
    @Resource
    private PurchaseHelp purchaseHelp;
    @Resource
    private SaasPaySheetHelper saasPaySheetHelper;
    @Resource
    private FundHelp fundHelp;
    @Resource
    private FundAccountFlowModel fundAccountFlowModel;
    @Resource
    private SaasRefundHelper saasRefundHelper;
    @Resource
    private PayPlanSheetService payPlanSheetService;
    @Resource
    private PayPlanSheetUserModel payPlanSheetUserModel;

    @Override
    public List<Integer> type() {
        return Arrays.asList(XbbRefTypeEnum.PAY_SHEET.getCode(), XbbRefTypeEnum.WRITE_OFF_PREPAY.getCode(), XbbRefTypeEnum.RED_WRITE_OFF_PAY.getCode(), XbbRefTypeEnum.RED_WRITE_OFF_PREPAY.getCode(), XbbRefTypeEnum.PREPAY.getCode(), XbbRefTypeEnum.RED_PREPAY.getCode(), XbbRefTypeEnum.BAD_PAY.getCode());
    }

    @Override
    public void save(WorkflowTransferPOJO workflowTransferPOJO, SaasNeedRedundantAttrPojo saasNeedRedundantAttrPojo) throws XbbException {

        // 文件柜
        saveDataCabinetFile(workflowTransferPOJO);

        String corpid = workflowTransferPOJO.getCorpid();
        Data pojoData = workflowTransferPOJO.getData();
        Integer subBusinessType = pojoData.getSubBusinessType();
        JSONObject data = pojoData.getData();
        Long dataId = pojoData.getId();
        PaySheetTypeEnum paySheetTypeEnum = PaySheetTypeEnum.getByBusinessType(subBusinessType);
        SheetTypeEnum sheetTypeEnum = paySheetTypeEnum.getSheetTypeEnum();
        if (Objects.equals(sheetTypeEnum, SheetTypeEnum.WRITE_OFF_PAY)) {
            //已核销
            workFlowWriteOffSave(workflowTransferPOJO, saasNeedRedundantAttrPojo);
        } else if (Objects.equals(sheetTypeEnum, SheetTypeEnum.WRITE_OFF_PREPAY)) {
            //预付款核销
            workFlowWriteOffSave(workflowTransferPOJO, saasNeedRedundantAttrPojo);
        } else if (Objects.equals(sheetTypeEnum, SheetTypeEnum.RED_WRITE_OFF_PAY)) {
            //红冲已核销
            workFlowRedSave(workflowTransferPOJO, saasNeedRedundantAttrPojo);
        } else if (Objects.equals(sheetTypeEnum, SheetTypeEnum.RED_WRITE_OFF_PREPAY)) {
            //红冲预付款核销
            workFlowRedSave(workflowTransferPOJO, saasNeedRedundantAttrPojo);
        }else if (Objects.equals(sheetTypeEnum, SheetTypeEnum.PREPAY)) {
            //预付款
            workFlowPrepaySave(workflowTransferPOJO, saasNeedRedundantAttrPojo);
        } else if (Objects.equals(sheetTypeEnum, SheetTypeEnum.RED_PREPAY)) {
            //红冲预付款余额
            workFlowPrepaySave(workflowTransferPOJO, saasNeedRedundantAttrPojo);
        } else if (Objects.equals(sheetTypeEnum, SheetTypeEnum.BAD_PAY)) {
            //坏账
            workFlowBadSave(workflowTransferPOJO, saasNeedRedundantAttrPojo);
        }

        //这里需要重置采购退货单里面的付款单信息
        Long returnedPurchaseId = saasNeedRedundantAttrPojo.getReturnedPurchaseId();
        if (returnedPurchaseId != null) {
            PaasFormDataEntity paasFormDataEntity = new PaasFormDataEntity();
            paasFormDataEntity.setId(dataId);
            paasFormDataEntity.setSerialNo(data.getString(BasicConstant.SERIAL_NO));
            saasRefundHelper.updateReturnedPurchasePaySheetId(returnedPurchaseId, paasFormDataEntity, corpid);
        }

        // api
        apiHook(workflowTransferPOJO);
        addLinkDataDynamic(workflowTransferPOJO);
        // log
        afterSaveLog(workflowTransferPOJO);
    }

    /**
     * 坏账付款单处理
     *
     * @param workflowTransferPOJO
     * @param saasNeedRedundantAttrPojo
     */
    private void workFlowBadSave(WorkflowTransferPOJO workflowTransferPOJO, SaasNeedRedundantAttrPojo saasNeedRedundantAttrPojo) throws XbbException {
        Data pojoData = workflowTransferPOJO.getData();
        Integer subBusinessType = pojoData.getSubBusinessType();
        String corpid = workflowTransferPOJO.getCorpid();
        Long dataId = pojoData.getId();
        JSONObject newData = pojoData.getData();
        Long formId = pojoData.getFormId();
        PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByFormId(formId, corpid);
        Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(paasFormExplainEntity.getExplains(), null);
        PayPlanSheetEntityExt payPlanSheetEntityExt = payPlanSheetModel.getByKey(dataId, corpid);

        PaySheetTypeEnum paymentSheetTypeEnum = PaySheetTypeEnum.getByBusinessType(subBusinessType);
        SheetTypeEnum sheetTypeEnum = paymentSheetTypeEnum.getSheetTypeEnum();
        SheetAttrPojo sheetAttrPojo = new SheetAttrPojo(sheetTypeEnum.getXbbRefTypeEnum());

        List<PayPlanSheetEntityExt> sonSheetList = null;
        double allAmount = 0D;
        //付款计划和合同对应的付款金额
        Map<Long, Double> contractIdToAmount = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, Double> paymentIdToAmount = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Set<Long> contractIds = new HashSet<>();
        Set<Long> paymentIds = new HashSet<>();
        //付款单的实际坏账金额
        Double sheetAmount = FastJsonHelper.getDoubleOrDefaultFromFormData(newData, PaySheetEnum.AMOUNT.getAttr(), 0D);
        //处理金额明细
        SaasFormSaveDTO saasFormSaveDTO = new SaasFormSaveDTO();
        saasFormSaveDTO.setExplainMap(explainMap);
        List<JSONObject> sonSheetDataList = saasSaveHelper.handleAmountDetail(saasFormSaveDTO, sheetAmount, sheetTypeEnum, sheetAttrPojo, newData, saasNeedRedundantAttrPojo.getAmountDetail(), allAmount, contractIdToAmount, paymentIdToAmount, contractIds, paymentIds);
        //处理付款计划并封装要更新的结果
        List<UpdateDataEntity> updatePayList = saasPayPlanHelper.handlePlan(sheetTypeEnum, newData, corpid, paymentIdToAmount, paymentIds);
        //处理采购合同并封装要更新的结果
        List<UpdateDataEntity> updateConList = purchaseHelp.handleContract(sheetTypeEnum, corpid, contractIdToAmount, contractIds);
        //插入付款单、子付款单
        sonSheetList = saasPaySheetHelper.saveSheetSon(corpid, sonSheetDataList, payPlanSheetEntityExt, payPlanSheetEntityExt.getUuid());
        //更新付款计划/合同
        saasPayPlanHelper.savePayPlan(corpid, updatePayList, "PayPlanSheetServiceImpl.badSave：新建坏账付款单更新付款计划时失败");
        purchaseHelp.savePurchase(corpid, updateConList, "PayPlanSheetServiceImpl.badSave：新建坏账付款单更新合同时失败");
        //处理付款单团队-必须在团队保存后执行，需要用到付款款单的id
        try {
            TeamSavePaySheetPojo teamSavePaySheetPojo = new TeamSavePaySheetPojo(payPlanSheetEntityExt, sonSheetList, true, payPlanSheetEntityExt, saasNeedRedundantAttrPojo, null, true);
            payPlanSheetService.operateSheetTeam(teamSavePaySheetPojo.getPayPlanSheetEntityExt(), teamSavePaySheetPojo.getSheetList(), teamSavePaySheetPojo.getIgnoreMainSheet(), teamSavePaySheetPojo.getNewPaasFormDataEntity(), teamSavePaySheetPojo.getSaasNeedRedundantAttrPojo(), teamSavePaySheetPojo.getIsImport(), teamSavePaySheetPojo.getWorkflowTag());
        }catch (Exception e){
            log.error("处理付款单团队", e);
        }


    }

    /**
     * 预付款、红冲预付款余额付款单处理
     *
     * @param workflowTransferPOJO
     * @param saasNeedRedundantAttrPojo
     */
    private void workFlowPrepaySave(WorkflowTransferPOJO workflowTransferPOJO, SaasNeedRedundantAttrPojo saasNeedRedundantAttrPojo) throws XbbException {
        Data pojoData = workflowTransferPOJO.getData();
        Integer subBusinessType = pojoData.getSubBusinessType();
        String corpid = workflowTransferPOJO.getCorpid();
        Long dataId = pojoData.getId();
        JSONObject dataList = pojoData.getData();
        PayPlanSheetEntityExt payPlanSheetEntityExt = payPlanSheetModel.getByKey(dataId, corpid);
        Long formId = pojoData.getFormId();
        PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByFormId(formId, corpid);
        Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(paasFormExplainEntity.getExplains(), null);
        PaySheetTypeEnum paySheetTypeEnum = PaySheetTypeEnum.getByBusinessType(subBusinessType);
        SheetTypeEnum sheetTypeEnum = paySheetTypeEnum.getSheetTypeEnum();
        boolean redFlag = false;
        if (Objects.equals(sheetTypeEnum, SheetTypeEnum.RED_PREPAY)) {
            redFlag = true;
            Double amount = dataList.getDouble(PaySheetEnum.AMOUNT.getAttr());
            //金额置为负数
            dataList.put(PaySheetEnum.AMOUNT.getAttr(), Arith.mul(amount, -1));
        }
        //添加预付款余额
        saasPaySheetHelper.saveBySheet(payPlanSheetEntityExt);
        Double amount = FastJsonHelper.getDoubleOrDefaultFromFormData(dataList, PaySheetEnum.AMOUNT.getAttr(), 0D);
        Long accountId = FastJsonHelper.getLongOrDefaultFromFormData(dataList, PaySheetEnum.FUND_ACCOUNT.getAttr(), 0L);
        Long addTime = payPlanSheetEntityExt.getAddTime();
        Long sheetTime = fundHelp.getSheetTime4FundFlow(dataList, PaySheetEnum.REAL_PAY_TIME.getAttr(), explainMap, addTime);
        amount = Arith.mul(amount, -1);
        payAndPaymentSheetHelp.saveByPaymentSheetOrPaySheet(accountId, amount, corpid);
        //流水表日志记录
        FundAccountFlowEntity fundAccountFlowEntity = new FundAccountFlowEntity(corpid, DateTimeUtil.getInt(), payPlanSheetEntityExt.getCreatorId(), FundAccountFlowTypeEnum.PAY_SHEET.getCode(), payPlanSheetEntityExt.getId(), accountId, sheetTime, amount);
        fundAccountFlowModel.insert(fundAccountFlowEntity);
    }

    /**
     * 工作流红冲已核销、红冲预付款核销付款单处理
     *
     * @param workflowTransferPOJO
     * @param saasNeedRedundantAttrPojo
     */
    private void workFlowRedSave(WorkflowTransferPOJO workflowTransferPOJO, SaasNeedRedundantAttrPojo saasNeedRedundantAttrPojo) throws XbbException {
        Data pojoData = workflowTransferPOJO.getData();
        Integer subBusinessType = pojoData.getSubBusinessType();
        String corpid = workflowTransferPOJO.getCorpid();
        Long dataId = pojoData.getId();
        JSONObject newData = pojoData.getData();
        Long formId = pojoData.getFormId();
        PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByFormId(formId, corpid);
        Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(paasFormExplainEntity.getExplains(), null);
        PayPlanSheetEntityExt payPlanSheetEntityExt = payPlanSheetModel.getByKey(dataId, corpid);

        PaySheetTypeEnum paySheetTypeEnum = PaySheetTypeEnum.getByBusinessType(subBusinessType);
        SheetTypeEnum sheetTypeEnum = paySheetTypeEnum.getSheetTypeEnum();
        SheetAttrPojo sheetAttrPojo = new SheetAttrPojo(sheetTypeEnum.getXbbRefTypeEnum());
        List<PayPlanSheetEntityExt> sonSheetList = null;
        double allAmount = 0D;
        //付款计划和采购合同对应的付款金额
        Map<Long, Double> contractIdToAmount = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, Double> paymentIdToAmount = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Set<Long> contractIds = new HashSet<>();
        Set<Long> paymentIds = new HashSet<>();
        //处理金额明细
        SaasFormSaveDTO saasFormSaveDTO = new SaasFormSaveDTO();
        saasFormSaveDTO.setExplainMap(explainMap);
        Double sheetAmount = FastJsonHelper.getDoubleOrDefaultFromFormData(newData, PaySheetEnum.AMOUNT.getAttr(), 0D);
        List<JSONObject> sonSheetDataList = saasSaveHelper.handleAmountDetail(saasFormSaveDTO, sheetAmount, sheetTypeEnum, sheetAttrPojo, newData, saasNeedRedundantAttrPojo.getAmountDetail(), allAmount, contractIdToAmount, paymentIdToAmount, contractIds, paymentIds);
        Double amount = Arith.mul(sheetAmount, -1);
        //处理付款计划
        List<UpdateDataEntity> updatePayList = saasPayPlanHelper.handlePlan(sheetTypeEnum, newData, corpid, paymentIdToAmount, paymentIds);
        //处理采购合同
        List<UpdateDataEntity> updateConList = purchaseHelp.handleContract(sheetTypeEnum, corpid, contractIdToAmount, contractIds);
        //插入付款单、子付款单
        sonSheetList = saasPaySheetHelper.saveSheetSon(corpid, sonSheetDataList, payPlanSheetEntityExt, payPlanSheetEntityExt.getUuid());
        //更新付款计划/合同
        saasPayPlanHelper.savePayPlan(corpid, updatePayList, "PayPlanSheetServiceImpl.redSave：新建红冲付款单更新付款计划时失败");
        purchaseHelp.savePurchase(corpid, updateConList, "PayPlanSheetServiceImpl.redSave：新建红冲付款单更新采购合同时失败");
        Long accountId = FastJsonHelper.getLongOrDefaultFromFormData(newData, PaySheetEnum.FUND_ACCOUNT.getAttr(), 0L);
        Long addTime = payPlanSheetEntityExt.getAddTime();
        Long sheetTime = fundHelp.getSheetTime4FundFlow(newData, PaySheetEnum.REAL_PAY_TIME.getAttr(), explainMap, addTime);
        //账户余额变动 红冲金额未处理成负数
        payAndPaymentSheetHelp.saveByPaymentSheetOrPaySheet(accountId, amount, corpid);
        //流水表日志记录
        FundAccountFlowEntity fundAccountFlowEntity = new FundAccountFlowEntity(corpid, DateTimeUtil.getInt(), payPlanSheetEntityExt.getCreatorId(), FundAccountFlowTypeEnum.PAY_SHEET.getCode(), payPlanSheetEntityExt.getId(), accountId, sheetTime, sheetAmount);
        fundAccountFlowModel.insert(fundAccountFlowEntity);
        //处理付款单团队-必须在团队保存后执行，需要用到付款款单的id
        TeamSavePaySheetPojo teamSavePaySheetPojo = new TeamSavePaySheetPojo(payPlanSheetEntityExt, sonSheetList, true, payPlanSheetEntityExt, saasNeedRedundantAttrPojo, null, true);
        payPlanSheetService.operateSheetTeam(teamSavePaySheetPojo.getPayPlanSheetEntityExt(), teamSavePaySheetPojo.getSheetList(), teamSavePaySheetPojo.getIgnoreMainSheet(), teamSavePaySheetPojo.getNewPaasFormDataEntity(), teamSavePaySheetPojo.getSaasNeedRedundantAttrPojo(), teamSavePaySheetPojo.getIsImport(), teamSavePaySheetPojo.getWorkflowTag());


    }

    /**
     * 工作流已核销、预付款核销付款单处理
     *
     * @param workflowTransferPOJO
     * @param saasNeedRedundantAttrPojo
     */
    private void workFlowWriteOffSave(WorkflowTransferPOJO workflowTransferPOJO, SaasNeedRedundantAttrPojo saasNeedRedundantAttrPojo) throws XbbException {
        Data pojoData = workflowTransferPOJO.getData();
        Integer subBusinessType = pojoData.getSubBusinessType();
        String corpid = workflowTransferPOJO.getCorpid();
        Long dataId = pojoData.getId();
        JSONObject data = pojoData.getData();
        Long formId = pojoData.getFormId();
        PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByFormId(formId, corpid);
        Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(paasFormExplainEntity.getExplains(), null);
        PayPlanSheetEntityExt payPlanSheetEntityExt = payPlanSheetModel.getByKey(dataId, corpid);
        PaySheetTypeEnum paySheetTypeEnum = PaySheetTypeEnum.getByBusinessType(subBusinessType);
        SheetTypeEnum sheetTypeEnum = paySheetTypeEnum.getSheetTypeEnum();
        SheetAttrPojo sheetAttrPojo = new SheetAttrPojo(sheetTypeEnum.getXbbRefTypeEnum());
        //付款计划和采购合同对应的付款金额
        Map<Long, Double> contractIdToAmount = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, Double> paymentIdToAmount = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Set<Long> contractIds = new HashSet<>();
        Set<Long> paymentIds = new HashSet<>();
        List<PayPlanSheetEntityExt> sonSheetList = null;

        //回/付款单的实付回/付款金额
        Double sheetAmount;
        double allAmount = 0D;
        boolean writeOffPrepaymentFlag = SheetTypeEnum.isWriteOffPre(sheetTypeEnum);
        if (writeOffPrepaymentFlag) {
            //预付/付款核销，是用的核销金额
            sheetAmount = FastJsonHelper.getDoubleOrDefaultFromFormData(data, sheetAttrPojo.getAttrWriteOffAmount(), 0D);
        } else {
            sheetAmount = FastJsonHelper.getDoubleOrDefaultFromFormData(data, sheetAttrPojo.getAttrAmount(), 0D);
        }
        //处理付款单金额明细
        SaasFormSaveDTO saasFormSaveDTO = new SaasFormSaveDTO();
        saasFormSaveDTO.setExplainMap(explainMap);
        List<JSONObject> sonSheetDataList = saasSaveHelper.handleAmountDetail(saasFormSaveDTO, sheetAmount, sheetTypeEnum, sheetAttrPojo, data, saasNeedRedundantAttrPojo.getAmountDetail(),
                allAmount, contractIdToAmount, paymentIdToAmount, contractIds, paymentIds);
        //处理付款计划并封装要更新的结果：并把付款计划的已付金额增加及更改其付款状态等
        List<UpdateDataEntity> updatePayList = saasPayPlanHelper.handlePlan(sheetTypeEnum, data, corpid, paymentIdToAmount, paymentIds);
        //处理采购合同并封装要更新的结果：并把采购合同的已付金额增加等
        List<UpdateDataEntity> updateConList = purchaseHelp.handleContract(sheetTypeEnum, corpid, contractIdToAmount, contractIds);
        //插入付款单以及子付款单
        sonSheetList = saasPaySheetHelper.saveSheetSon(corpid, sonSheetDataList, payPlanSheetEntityExt, payPlanSheetEntityExt.getUuid());
        //更新付款计划/合同
        saasPayPlanHelper.savePayPlan(corpid, updatePayList, "PayPlanSheetServiceImpl.writeOffSave：新建已核销付款单更新付款计划时失败");
        purchaseHelp.savePurchase(corpid, updateConList, "PayPlanSheetServiceImpl.writeOffSave：新建已核销付款单更新采购合同时失败");
        if (writeOffPrepaymentFlag) {
            //核销预付款付款单新建时，减少预付款余额
            saasPaySheetHelper.saveBySheet(payPlanSheetEntityExt);
        } else {
            Long addTime = payPlanSheetEntityExt.getAddTime();
            Long accountId = FastJsonHelper.getLongOrDefaultFromFormData(data, PaySheetEnum.FUND_ACCOUNT.getAttr(), 0L);
            Long sheetTime = fundHelp.getSheetTime4FundFlow(data, PaySheetEnum.REAL_PAY_TIME.getAttr(), explainMap, addTime);
            //账户余额变动 付款取反
            sheetAmount = Arith.mul(sheetAmount, -1);
            payAndPaymentSheetHelp.saveByPaymentSheetOrPaySheet(accountId, sheetAmount, corpid);
            //流水表日志记录
            FundAccountFlowEntity fundAccountFlowEntity = new FundAccountFlowEntity(corpid, addTime, payPlanSheetEntityExt.getCreatorId(), FundAccountFlowTypeEnum.PAY_SHEET.getCode(), payPlanSheetEntityExt.getId(), accountId, sheetTime, sheetAmount);
            fundAccountFlowModel.insert(fundAccountFlowEntity);
        }
        //处理付款单团队-必须在团队保存后执行，需要用到付款款单的id
        TeamSavePaySheetPojo teamSavePaySheetPojo = new TeamSavePaySheetPojo(payPlanSheetEntityExt, sonSheetList, true, payPlanSheetEntityExt, saasNeedRedundantAttrPojo, null, true);
        payPlanSheetService.operateSheetTeam(teamSavePaySheetPojo.getPayPlanSheetEntityExt(), teamSavePaySheetPojo.getSheetList(), teamSavePaySheetPojo.getIgnoreMainSheet(), teamSavePaySheetPojo.getNewPaasFormDataEntity(), teamSavePaySheetPojo.getSaasNeedRedundantAttrPojo(), teamSavePaySheetPojo.getIsImport(), teamSavePaySheetPojo.getWorkflowTag());
        // 添加项目日志，及推送消息
        PaymentSheetSaveDTO paymentSheetSaveDTO = new PaymentSheetSaveDTO();
        BeanUtil.copyProperties(saasFormSaveDTO, paymentSheetSaveDTO);
        //createLogAndMessage(PushTypeEnum.PAYMENT_SHEET_ADD, data, corpid, userId, paymentSheetEntityExt, I18nMessageUtil.getMessage(CustomerCommunicateConstant.PAYMENT_SHEET_ADD_CONTRACT), I18nMessageUtil.getMessage(PaymentPushConstant.PAYMENT_SHEET_ADD_TITLE), I18nMessageUtil.getMessage(PaymentPushConstant.PAYMENT_SHEET_ADD_CONTENT), distributorMark);
    }

    @Override
    public void update(WorkflowTransferPOJO workflowTransferPOJO, SaasNeedRedundantAttrPojo saasNeedRedundantAttrPojo) throws XbbException {

        // 文件柜
        saveDataCabinetFile(workflowTransferPOJO);

        String corpid = workflowTransferPOJO.getCorpid();
        Data pojoData = workflowTransferPOJO.getData();
        JSONObject data = pojoData.getData();

        SheetTypeEnum sheetTypeEnum = SheetTypeEnum.getByCodeRefTypeEnum(data.getString(PaymentSheetEnum.PAYMENT_SHEET_TYPE.getAttr()), XbbRefTypeEnum.PAYMENT_SHEET);

        PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByFormId(pojoData.getFormId(), corpid);
        Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(paasFormExplainEntity.getExplains());
        //更新子单信息
        // TODO 加了经销商标识，需要核对
        List<UpdateDataEntity> updateList = payAndPaymentSheetHelp.updateSonDataList4Sheet(corpid, sheetTypeEnum, paasFormExplainEntity.getDistributorMark(), saasNeedRedundantAttrPojo.getAmountDetail(), explainMap);
        if (CollectionsUtil.isNotEmpty(updateList)) {
            payPlanSheetModel.updateBatch(updateList, corpid);
        }

        // api
        apiHook(workflowTransferPOJO);
        // log
        afterUpdateLog(workflowTransferPOJO);


    }

    @Override
    public void updateBack(Long taskId, WorkflowTransferPOJO workflowTransferPOJO) throws XbbException {
        try {
            String corpid = workflowTransferPOJO.getCorpid();
            Long backupDataId = workflowTransferPOJO.getBackupDataId();
            Long dataId = workflowTransferPOJO.getData().getId();
            WorkflowBackupDataEntity workflowBackupDataEntity = workflowBackupDataModel.getByKey(backupDataId, corpid);
            if (Objects.nonNull(workflowBackupDataEntity)) {
                JSONObject data = workflowBackupDataEntity.getData();

                replenishAttrForBackupData(workflowTransferPOJO.getData().getData(), data);

                PayPlanSheetEntityExt payPlanSheetEntityExt = new PayPlanSheetEntityExt();
                payPlanSheetEntityExt.setId(dataId);
                payPlanSheetEntityExt.setCorpid(corpid);
                payPlanSheetEntityExt.setData(data);
                payPlanSheetEntityExt.setSerialNo(data.getString(FieldTypeEnum.SERIALNO.getAlias()));
                // 获取负责人
                payPlanSheetEntityExt.setOwnerId(getOwnerId(data));
                payPlanSheetEntityExt.setDepartmentId(data.getLong(FieldTypeEnum.DEPARTMENTID.getAlias()));

                FormDataUtil.removeSystemData(data);
                if (Objects.equals(workflowTransferPOJO.getOperate(), WorkflowOperateEnum.UPDATE.getType())) {
                    payPlanSheetEntityExt.setFlowStatus(FlowStatusEnum.PASS.getType());
                }
                payPlanSheetModel.update(payPlanSheetEntityExt);

                // 回退被删掉的子表单
                updateBackSubForm(payPlanSheetEntityExt, corpid, IndexTypeEnum.IDX_SAAS_PAYPLAN_SHEET_SUB);
                //回退被删掉的富文本
                updateBackRichText(taskId, workflowTransferPOJO);
            }
        } catch (Exception e) {
            log.error("com.xbongbong.workflow.service.strategy.data.impl.WorkflowPaySheetStrategy.updateBack error ", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }

    @Override
    public void approvalFailed(Long taskId, WorkflowTransferPOJO workflowTransferPOJO, Integer taskType) throws XbbException {
        try {
            String corpid = workflowTransferPOJO.getCorpid();
            Data workflowData = workflowTransferPOJO.getData();
            Long dataId = workflowData.getId();
            Long formId = workflowData.getFormId();
            Integer businessType = workflowData.getBusinessType();
            Integer saasMark = workflowData.getSaasMark();
            PayPlanSheetEntityExt payPlanSheetEntityExt = new PayPlanSheetEntityExt();
            payPlanSheetEntityExt.setId(dataId);
            if (Objects.equals(TaskTypeEnum.REVOKE.getType(), taskType)) {
                payPlanSheetEntityExt.setFlowStatus(FlowStatusEnum.REVOKE.getType());
            } else {
                payPlanSheetEntityExt.setFlowStatus(FlowStatusEnum.REJECT.getType());
            }
            payPlanSheetEntityExt.setCorpid(corpid);
            payPlanSheetEntityExt.setUpdateTime(DateTimeUtil.getInt());
            payPlanSheetModel.update(payPlanSheetEntityExt);
            // 子表单
            DelEnum del = DelEnum.APPROVE_FAILED;

            paasFormSubDataModel.deleteBatchByDataId(Collections.singletonList(dataId), corpid, IndexTypeEnum.IDX_SAAS_PAYPLAN_SHEET_SUB, del);
            //富文本
            deleteFormRichText(dataId, corpid, formId, businessType, saasMark, DelEnum.NORMAL);
            // 团队
            List<PayPlanSheetUserEntity> payPlanSheetUserEntities = payPlanSheetUserModel.getPaySheetUserIdList(corpid, dataId, null);
            if (CollectionsUtil.isNotEmpty(payPlanSheetUserEntities)) {
                payPlanSheetUserModel.deleteBatchUser(corpid, payPlanSheetUserEntities, del.getDel());
            }
        } catch (Exception e) {
            log.error("com.xbongbong.workflow.service.strategy.data.impl.WorkflowPaySheetStrategy.approvalFailed error ", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }
}
